import { useRef, useState } from "react";
import { useBooks } from "./book-context"
import { SQLiteTableWithColumns } from "drizzle-orm/sqlite-core";
import { like } from "drizzle-orm";

interface IUsePaginationData {
    model: SQLiteTableWithColumns<any>
}

interface IQuery<T> {
    page: number,
    size: number,
    keyword?: string,
    searchKey?: keyof T
}

interface PaginationResult<T> {
    // 数据list
    list: T[] | undefined
    // 是否加载中
    loading: boolean
    // 报错
    error: Error | null
    // 分页
    page: number
    // 总数
    total: number
    // 是否能下一页
    hasNext: boolean
    // 是否能上一页
    hasPrev: boolean
    // 加载数据
    load: (data?: Partial<IQuery<T>>) => Promise<void>
    // 上一页
    prev: () => Promise<void>
    // 下一页
    next: () => Promise<void>
    // 刷新
    refresh: () => Promise<void>
    // 搜索数据
    search: (keyword: string, searchKey: keyof T) => Promise<void>
}

/**
 * 通用分页查询
 * @param params 
 * @returns 
 */
const usePagination = <T>(params: IUsePaginationData): PaginationResult<T> => {
    const db = useBooks();
    const [list, setList] = useState<T[]>();
    const [total, setTotal] = useState(0);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<Error | null>(null);
    const queryRef = useRef<IQuery<T>>({
        page: 1,
        size: 10,
        keyword: '',
        searchKey: undefined
    });

    const getQuery = () => {
        const { keyword, searchKey } = queryRef.current;
        if (keyword && searchKey) {
            return like(params.model[searchKey], `%${keyword}%`);
        }
        return undefined;
    };

    const load = async (data?: Partial<IQuery<T>>) => {
        try {
            setLoading(true);
            setError(null);
            
            if (data) {
                queryRef.current = { ...queryRef.current, ...data };
            }

            const { page, size } = queryRef.current;
            const whereClause = getQuery();

            // 获取总数
            const countResult = await db
                .select({ value: params.model })
                .from(params.model)
                .where(whereClause)
                .$dynamic();
            
            setTotal(countResult.length);

            // 获取列表数据
            const query = db
                .select()
                .from(params.model)
                .limit(size)
                .offset((page - 1) * size);

            if (whereClause) {
                query.where(whereClause);
            }

            const val = await query;
            setList(val);
        } catch (err) {
            setError(err instanceof Error ? err : new Error('未知错误'));
        } finally {
            setLoading(false);
        }
    };

    const prev = async () => {
        if (queryRef.current.page > 1) {
            queryRef.current.page--;
            await load();
        }
    };

    const next = async () => {
        if (hasNext) {
            queryRef.current.page++;
            await load();
        }
    };

    const refresh = async () => {
        queryRef.current.page = 1;
        await load();
    };

    const search = async (keyword: string, searchKey: keyof T) => {
        queryRef.current.keyword = keyword;
        queryRef.current.searchKey = searchKey;
        queryRef.current.page = 1;
        await load();
    };

    const hasNext = (queryRef.current.page * queryRef.current.size) < total;
    const hasPrev = queryRef.current.page > 1;

    return {
        list,
        loading,
        error,
        total,
        page: queryRef.current.page,
        hasNext,
        hasPrev,
        load,
        prev,
        next,
        refresh,
        search
    };
};

export default usePagination;